package com.whfc.emp.service.impl;

import com.alibaba.fastjson.JSON;
import com.whfc.common.constant.QueueConst;
import com.whfc.common.enums.AppWarnModuleType;
import com.whfc.emp.dao.AppEmpWarnMapper;
import com.whfc.emp.dao.AppEmpWarnRuleMapper;
import com.whfc.emp.dao.ClassMeetingMapper;
import com.whfc.emp.entity.AppEmpWarn;
import com.whfc.emp.entity.ClassMeeting;
import com.whfc.emp.enums.AppEmpWarnRuleType;
import com.whfc.emp.manager.AppEmpDataManager;
import com.whfc.emp.service.AppWorkPlanService;
import com.whfc.emp.service.ClassMeetingService;
import com.whfc.entity.dto.Apply.rep.ClassMeetingInfoRep;
import com.whfc.entity.dto.Apply.rep.WorkPlan;
import com.whfc.entity.dto.Apply.req.AppEntryApplicationReq;
import com.whfc.entity.dto.Apply.req.MeetingDto;
import com.whfc.entity.dto.msg.AppMsgToUserDTO;
import com.whfc.entity.dto.msg.PushMsgDTO;
import com.whfc.fuum.entity.SysEmpUser;
import com.whfc.fuum.entity.SysUser;
import com.whfc.fuum.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

import static java.util.Collections.emptyList;

@Slf4j
@DubboService(interfaceClass = ClassMeetingService.class, version = "1.0.0",timeout = 30000)
public class ClassMeetingServiceImpl implements ClassMeetingService {

    @Resource
    private ClassMeetingMapper classMeetingMapper;

    @Autowired
    private AppWorkPlanService appWorkPlanService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private AppEmpDataManager appEmpDataManager;

    @DubboReference(interfaceClass = SysUserService.class, version = "1.0.0")
    private SysUserService sysUserService;

    @Autowired
    private AppEmpWarnMapper appEmpWarnMapper;

    @Autowired
    private AppEmpWarnRuleMapper appEmpWarnRuleMapper;

    @Override
    public ClassMeeting selectByPrimaryKey(Integer id) {
        return classMeetingMapper.selectByPrimaryKey(id);
    }

    @Override
    public int deleteByPrimaryKey(Long id) {
        return classMeetingMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insert(ClassMeeting record) {
        return classMeetingMapper.insert(record);
    }

    @Override
    public int insertSelective(ClassMeeting record) {
        int i = classMeetingMapper.insertSelective(record);
        if(i == 0){
            return 0;
        }
        return record.getId();
    }

    @Override
    public int updateByPrimaryKeySelective(ClassMeeting record) {
        return classMeetingMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(ClassMeeting record) {
        return classMeetingMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<ClassMeeting> selectByPlanId(Long planId) {
        return classMeetingMapper.selectByPlanId(planId);
    }

    @Override
    public List<ClassMeeting> selectByCreateUser(Long createUser) {
        return classMeetingMapper.selectByCreateUser(createUser);
    }

    @Override
    public List<ClassMeeting> selectByMeetingType(Integer meetingType) {
        return classMeetingMapper.selectByMeetingType(meetingType);
    }

    @Override
    public List<ClassMeetingInfoRep> selectByMeetingDateEndUserId(String startTimeBegin, String startTimeEnd, Integer id) {
        return classMeetingMapper.selectByMeetingDateEndUserId(startTimeBegin,startTimeEnd,id);
    }

    @Override
    public List<ClassMeetingInfoRep> selectByMeetingDateEndCreateUser(String startTimeBegin, String startTimeEnd, Integer id) {
        return classMeetingMapper.selectByMeetingDateEndCreateUser(startTimeBegin,startTimeEnd,id);
    }

    @Override
    public ClassMeetingInfoRep selectByMeetingDateEndId(Integer id) {

        return classMeetingMapper.selectByMeetingDateEndId(id);
    }

    @Override
    public List<MeetingDto> meetingList(AppEntryApplicationReq req) {
        return classMeetingMapper.meetingList(req);
    }

    @Override
    public List<ClassMeetingInfoRep> selectByMeetingId(Integer id) {
        return classMeetingMapper.selectByMeetingId(id);
    }

    @Override
    public List<AppMsgToUserDTO> sendAlarmMessageToWorkPlanGuardians(String title, String alarmMessage, Integer classMeetingId) {
        if (StringUtils.isEmpty(alarmMessage) || classMeetingId == null){
//            throw new BizException(ResultEnum.FAILURE.getCode(), "缺少报警信息");
            log.error("缺少报警信息 alarmMessage:{}, workPlanId:{}", alarmMessage, classMeetingId);
            return emptyList();
        }
        ClassMeeting classMeeting = classMeetingMapper.selectByPrimaryKey(classMeetingId);
        if (classMeeting == null){
//            throw new BizException(ResultEnum.FAILURE.getCode(), "无效工作计划");
            log.error("无效工作计划 {}", classMeetingId);
            return emptyList();
        }
        List<Integer> guardianIds = appWorkPlanService.getGuardianIdsByWorkPlanId(classMeeting.getPlanId());

        Integer ruleId = appEmpWarnRuleMapper.selectByRuleType(AppEmpWarnRuleType.CLASSMEETING_CHECKIN.value(), 220);

        AppEmpWarn appEmpWarn = new AppEmpWarn();
        appEmpWarn.setTriggerObjectId(String.valueOf(classMeeting.getId()));
        appEmpWarn.setDeptId(220);
        appEmpWarn.setLat(0.0);
        appEmpWarn.setLng(0.0);
        appEmpWarn.setRuleId(ruleId);
        appEmpWarn.setRuleType(AppEmpWarnRuleType.CLASSMEETING_CHECKIN.value());
        appEmpWarn.setTriggerTime(new Date());
        appEmpWarnMapper.insertSelective(appEmpWarn);

        return pushAlarmMessageToGuardians(title, alarmMessage, appEmpWarn, guardianIds);
    }

    private List<AppMsgToUserDTO> pushAlarmMessageToGuardians(String title, String alarmMessage, AppEmpWarn appEmpWarn, List<Integer> guardianIds) {
        if (amqpTemplate == null) {
            log.error("RabbitMQ未配置，报警消息：{}", alarmMessage);
            return emptyList();
        }

        if (guardianIds == null || guardianIds.isEmpty()) {
            log.warn("报警记录【{}】没有配置旁站监护人员，无法推送报警消息", appEmpWarn.getId());
            return emptyList();
        }

        List<AppMsgToUserDTO> toUserList = new ArrayList<>();
        try {
            // 构建接收人列表
            for (Integer guardianId : guardianIds) {
                AppMsgToUserDTO userDTO = new AppMsgToUserDTO();
//                AppEmpDTO empInfo = appEmpMapper.selectEmpDTOById(guardianId);
                SysEmpUser sysEmpUser = sysUserService.getEmpUser(guardianId);
                if (sysEmpUser == null) continue;
                userDTO.setUserId(sysEmpUser.getSysUserId());
                // 查询监护人员详细信息，补全username和phone字段
                SysUser sysUser = sysUserService.getUserById(sysEmpUser.getSysUserId());
                if (sysUser != null) {
                    userDTO.setUsername(sysUser.getUsername()); // 设置用户名（人员姓名）
                    userDTO.setPhone(sysUser.getPhone());      // 设置手机号
                } else {
                    // 如果查询不到人员信息，设置默认值
                    userDTO.setUsername("未知用户");
                    userDTO.setPhone("");
                }
                toUserList.add(userDTO);
            }

            // 设置默认消息渠道：PC(3)和APP(1)
            List<Integer> msgChannelList = Arrays.asList(3, 1); // 3=后台(PC), 1=小程序(APP)

            // 使用PushMsgDTO封装推送消息
            PushMsgDTO pushMsgDTO = new PushMsgDTO();
            pushMsgDTO.setTitle(title);
            pushMsgDTO.setContent(alarmMessage);
            pushMsgDTO.setTime(new Date());
            pushMsgDTO.setModuleType(AppWarnModuleType.EMP.value()); // 安全报警类型
            pushMsgDTO.setMsgObjectId(String.valueOf(appEmpWarn.getId()));
            pushMsgDTO.setDeptId(220);
            pushMsgDTO.setToUserList(toUserList);
            pushMsgDTO.setMsgChannelList(msgChannelList);
            pushMsgDTO.setRuleType(AppEmpWarnRuleType.CLASSMEETING_CHECKIN.value());

            // 发送到fanout.push_msg交换机
            amqpTemplate.convertAndSend(QueueConst.PUSH_MSG_EXCHANGE, "", JSON.toJSONString(pushMsgDTO));

            log.info("报警消息推送给旁站监护人员成功：{}，接收人：{}", alarmMessage, guardianIds);
        } catch (Exception e) {
            log.error("报警消息推送失败：{}", e.getMessage());
        }

        return toUserList;
    }
}